/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * BSPanel.java
 *
 * Created on 3-May-2009, 4:04:10 PM
 */

package jogs.client.games.bs;

import java.io.*;
import java.net.*;
import java.util.*;
import jogs.client.games.GameClientPanel;
import jogs.client.games.Card;

import javax.swing.*;

/**
 *
 * @author lanctot
 */
public class BSPanel extends GameClientPanel {

    String[] args;

    private Socket socket;

    private BufferedReader in;
    private PrintStream out;

    boolean creator = false;
    boolean play_random = false;

    private ArrayList<Card> myHand;
    private HashMap<String, Integer> handSizes;
    private HashMap<String, JLabel> cardLabels;

    private ArrayList<Card> selectedCards; 

    /** Creates new form BSPanel */
    public BSPanel(boolean init) {
      if (init)
      {
        initComponents();
        initCards();
      }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    backgroundLabel = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    jTextPane1 = new javax.swing.JTextPane();
    jLayeredPane1 = new javax.swing.JLayeredPane();
    jLabel1 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    quantityBox = new javax.swing.JComboBox();
    cardBox = new javax.swing.JComboBox();
    okButton = new javax.swing.JButton();
    bsButton = new javax.swing.JButton();
    jProgressBar1 = new javax.swing.JProgressBar();

    setBackground(new java.awt.Color(255, 251, 226));

    backgroundLabel.setFont(new java.awt.Font("Serif", 1, 72)); // NOI18N
    backgroundLabel.setText("BS");

    jTextPane1.setBackground(new java.awt.Color(254, 254, 254));
    jTextPane1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
    jScrollPane1.setViewportView(jTextPane1);

    jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/tabletop_wide.jpg"))); // NOI18N
    jLabel1.setText("jLabel1");
    jLabel1.setBounds(0, 0, 760, 690);
    jLayeredPane1.add(jLabel1, javax.swing.JLayeredPane.DEFAULT_LAYER);

    jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cards/b1fv.png"))); // NOI18N
    jLabel3.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        jLabel3MouseClicked(evt);
      }
    });
    jLabel3.setBounds(350, 280, 70, 100);
    jLayeredPane1.add(jLabel3, javax.swing.JLayeredPane.PALETTE_LAYER);

    quantityBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4", "5", "6" }));
    quantityBox.setBounds(290, 390, 80, 27);
    jLayeredPane1.add(quantityBox, javax.swing.JLayeredPane.PALETTE_LAYER);

    cardBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Aces", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s", "Jacks", "Queens", "Kings", "Jokers" }));
    cardBox.setBounds(400, 390, 86, 27);
    jLayeredPane1.add(cardBox, javax.swing.JLayeredPane.PALETTE_LAYER);

    okButton.setText("OK");
    okButton.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        okButtonMouseReleased(evt);
      }
    });
    okButton.setBounds(340, 430, 90, 30);
    jLayeredPane1.add(okButton, javax.swing.JLayeredPane.PALETTE_LAYER);

    bsButton.setText("BS!");
    bsButton.setBounds(340, 240, 90, 30);
    jLayeredPane1.add(bsButton, javax.swing.JLayeredPane.PALETTE_LAYER);

    jProgressBar1.setBackground(new java.awt.Color(1, 1, 1));

    org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(layout.createSequentialGroup()
        .add(jLayeredPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 755, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(layout.createSequentialGroup()
            .add(31, 31, 31)
            .add(backgroundLabel))
          .add(layout.createSequentialGroup()
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
              .add(jProgressBar1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE)
              .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE))))
        .addContainerGap())
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(layout.createSequentialGroup()
        .add(backgroundLabel)
        .add(15, 15, 15)
        .add(jProgressBar1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 18, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 550, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
      .add(jLayeredPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE)
    );
  }// </editor-fold>//GEN-END:initComponents

    private void initCards()
    {
      cardLabels = new HashMap<String, JLabel>();
      selectedCards = new ArrayList<Card>(); 

      /*
      JLabel label = new JLabel();
      //System.out.println(c.toString());

      String suits = "cshd";

      for (int i = 1; i <= 13; i++)
        for (int j = 0; j < 4; j++)
      {
        String cstr = i + "" + suits.charAt(j);
        label.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cards/"+cstr+".png"))); // NOI18N
        //label.setVisible(false);

        cardLabels.put(cstr, label);
      }
      */
    }

    private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseClicked
      // TODO add your handling code here:
      System.out.println("Middle card clicked!" + evt.getX() + " " +evt.getY());
}//GEN-LAST:event_jLabel3MouseClicked

    private void okButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_okButtonMouseReleased
      // TODO add your handling code here:
      int quantity = quantityBox.getSelectedIndex() + 1;
      int card = cardBox.getSelectedIndex() + 1;

      System.out.println(quantity + " " + card);

      out.println("@MOVE:" + quantity + "-" + card);
    }//GEN-LAST:event_okButtonMouseReleased


  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JLabel backgroundLabel;
  private javax.swing.JButton bsButton;
  private javax.swing.JComboBox cardBox;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLayeredPane jLayeredPane1;
  private javax.swing.JProgressBar jProgressBar1;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JTextPane jTextPane1;
  private javax.swing.JButton okButton;
  private javax.swing.JComboBox quantityBox;
  // End of variables declaration//GEN-END:variables

  public void mainloop()
  {
    Random r = new Random();
    String name = (play_random ? "randomuser" : "clientuser");
    out.println("@NAME:" + name + r.nextInt(100));

    if (creator)
      out.println("@CREATE:BS,4");
    
    String line = "";
    try
    {
      line = "";

      while (line != null)
      {
        line = in.readLine();

        System.out.println("Received: " + line);
        // do something with it

        handle(line.trim());
      }
    }
    catch (Exception e)
    {
      e.printStackTrace(); 
    }
  }
  
  void handleNewPlayer(String details)
  {
    System.out.println("handling new player: " + details);
    jTextPane1.setText(jTextPane1.getText() + details + " has joined the game. \n");
  }

  void toggleSelected(Card c, int x, int y, boolean selected)
  {
    if (selected)
      selectedCards.add(c);
    else
      selectedCards.remove(c);
    
    JLabel label = cardLabels.get(c.toString());
    label.setBounds(x, y, 71, 100);
  }

  void placeCard(Card c, int x, int y)
  {
    JLabel label = cardLabels.get(c.toString());
    if (label == null)
    {
      label = new JLabel();
      label.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cards/"+c.toString()+".png"))); // NOI18N
      cardLabels.put(c.toString(), label);
    }

    //JLabel label = cardLabels.get(c.toString());

    label.setBounds(x, y, 71, 100);

    label.addMouseListener(new CardListener(c, this, x, y));

    jLayeredPane1.add(label, javax.swing.JLayeredPane.PALETTE_LAYER);
    
    label.setVisible(true);
  }

  void showHand()
  {
    double width = 600;
    double gap = width/myHand.size();

    for (int i = myHand.size()-1; i >= 0; i--)
    {
      placeCard(myHand.get(i), (int)(50 + i*gap), 575);
    }

  }

  void handleStart(String details)
  {
    myHand = new ArrayList<Card>();
    handSizes = new HashMap<String, Integer>();

    String[] handInfo = details.split(";");

    for (String hi : handInfo)
    {
      //System.out.println(hi);
      
      if (hi.indexOf("=") >= 0)
      {
        // not my hand
        String[] hparts = hi.split("=");
        handSizes.put(hparts[0], Integer.parseInt(hparts[1]));
      }
      else
      {
        // my hand
        String[] cards = hi.split(",");
        for (String cstr : cards)
        {
          Card card = new Card(cstr);
          //System.out.println(card.toString());
          myHand.add(card);
        }
      }
    }

    /* Sort the hand.. we can do this better */

    ArrayList<Card> sortedHand = new ArrayList<Card>();
    String suitOrder = "cshd";
    while(myHand.size() > 0)
    {
      int minimum = 10000000;
      int minIndex = 0;
      Card minCard = null;

      int i = 0;
      for (Card c : myHand)
      {
        int cval = c.getRank()*100 + suitOrder.indexOf("" + c.getSuit());
        //System.out.println(cval);
        if (cval < minimum)
        {
          minimum = cval;
          minIndex = i;
          minCard = c;
        }

        i++;
      }

      //System.out.println(minCard.toString());
      
      myHand.remove(minIndex);
      sortedHand.add(minCard);
    }

    myHand = sortedHand;

    showHand();
  }

    // Handles incoming network messages (lobby)
    public boolean handle(String line)
    {
    	if(line == null)
    		return true;
    	String details = null;
  		String command = null;


  		//all commands start with a @ and end with a :
  		int begin = line.indexOf('@');
  		int end = line.indexOf(':');

  		//if @ and : are not in message than it is not a command
  		if(begin == -1 || end == -1)
  		{
  			//this.send("@ERROR:Not a valid command");
  			return false;
  		}

  		//get the command out of the message
  		command = line.substring(begin, end);

  		//if command has details
  		if(line.length() > end+1)
  			details = line.substring(end+1);
  		//System.out.println("command: " + command);
  		//System.out.println("details: " + details);
  		//System.out.println(command.equals("@NEWUSER"));
      if (command.equals("@NEWPLAYER"))
        handleNewPlayer(details);
      else if (command.equals("@START"))
        handleStart(details);
      else
        return false;

      return true;
    }

  public void handleCommand(String s)
  {
    if (s.equals("/start"))
      out.println("@MOVE:start");
  }

  public void run()
  {
    initComponents();
    initCards(); 

    if (args.length > 1 && args[1].equals("create"))
      creator = true;
    
    if (args.length > 2 && args[2].equals("random"))
      play_random = true; 


    System.out.println("Connecting...");

    // connect to stand alone server
    try
    {
      Socket s = new Socket("localhost", 10000);
      BufferedReader _in = new BufferedReader(new InputStreamReader(s.getInputStream()));
      PrintStream _out = new PrintStream(s.getOutputStream());

      socket = s;
      in = _in;
      out = _out;

      System.out.println("Connected. Starting main loop.");

      //f.setSize(920,730);
      //f.setVisible(true);

      setSize(916,692);
      setVisible(!play_random);

      mainloop();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  public void startStandAlone(String[] _args)
  {
    args = _args;
    Thread t = new Thread(this);
    t.start();
  }
}
